/**
 * <b>项目名：</b>monitor<br/>
 * <b>包名：</b>org.monitor.main<br/>
 * <b>文件名：</b>Common.java<br/>
 * <b>版本信息：</b> @version 1.0.0<br/>
 * <b>日期：</b>2013-6-8-下午6:09:23<br/>
 * <b>Copyright (c)</b> 2013魅族公司-版权所有<br/>
 *
 */

package org.monitor.common;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.log4j.Logger;
import org.monitor.beans.RequestParam;
import org.monitor.command.RegistServerCommand;
import org.monitor.main.MClient;
import org.monitor.main.Main;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScriptableObject;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * <b>类名称：</b>Common<br/>
 * <b>类描述：</b>
 * 
 * <pre>
 </pre>
 * 
 * <br/>
 * <b>创建人：</b>张军强<br/>
 * <b>修改人：</b>张军强<br/>
 * <b>修改时间：</b>2013-6-8 下午6:09:23<br/>
 * <b>修改备注：</b><br/>
 * 
 * @version 1.0.0<br/>
 */

public class Common {
	
	private static Logger logger = Logger.getLogger(Common.class);
	
	private static DefaultHttpClient httpClient=null;
	private static DefaultHttpClient httpServer=null;
	
	public static synchronized DefaultHttpClient getHttpClient(String url) {

		int serverPort = 80;//Main.getConfig().getProperty("server.port")==null?80:Integer.parseInt(Main.getConfig().getProperty("server.port"));
		int clentPort =80;// Main.getConfig().getProperty("client.port")==null?80:Integer.parseInt(Main.getConfig().getProperty("client.port"));
		if (url.contains(":" + serverPort)) {

			if (httpServer == null) {
				// Log.v(TAG, "->> httpClient is null ->> do getHttpClient");
				// 设置组件参数, HTTP协议的版本,1.1/1.0/0.9
				HttpParams params = new BasicHttpParams();
				HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
				HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
				HttpProtocolParams.setUseExpectContinue(params, true);

				// 设置连接超时时间
				int REQUEST_TIMEOUT = 10 * 1000; // 设置请求超时10秒钟
				int SO_TIMEOUT = 10 * 1000; // 设置等待数据超时时间10秒钟
				HttpConnectionParams.setConnectionTimeout(params, REQUEST_TIMEOUT);
				HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT);
				ConnManagerParams.setTimeout(params, 1000); // 从连接池中取连接的超时时间

				// 设置访问协议
				SchemeRegistry schreg = new SchemeRegistry();
				schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), clentPort));
				// schreg.register(new Scheme("https", SSLSocketFactory., 443));

				// 使用线程安全的连接管理来创建HttpClient
				ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schreg);
				httpServer = new DefaultHttpClient(conMgr, params);
			}
			return httpServer;

		} else {

			if (httpClient == null) {
				// Log.v(TAG, "->> httpClient is null ->> do getHttpClient");
				// 设置组件参数, HTTP协议的版本,1.1/1.0/0.9
				HttpParams params = new BasicHttpParams();
				HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
				HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
				HttpProtocolParams.setUseExpectContinue(params, true);

				// 设置连接超时时间
				int REQUEST_TIMEOUT = 10 * 1000; // 设置请求超时10秒钟
				int SO_TIMEOUT = 10 * 1000; // 设置等待数据超时时间10秒钟
				HttpConnectionParams.setConnectionTimeout(params, REQUEST_TIMEOUT);
				HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT);
				ConnManagerParams.setTimeout(params, 1000); // 从连接池中取连接的超时时间

				// 设置访问协议
				SchemeRegistry schreg = new SchemeRegistry();
				schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), serverPort));
				// schreg.register(new Scheme("https", SSLSocketFactory., 443));

				// 使用线程安全的连接管理来创建HttpClient
				ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schreg);
				httpClient = new DefaultHttpClient(conMgr, params);
			}
			return httpClient;

		}
	}

	public static String getProjectPath() throws UnsupportedEncodingException {

		URL url = Main.class.getProtectionDomain().getCodeSource().getLocation();

		String filePath = URLDecoder.decode(url.getPath(), "utf-8");

		if (filePath.endsWith(".jar")) {

			filePath = filePath.substring(0, filePath.lastIndexOf("/") + 1);

		}

		File file = new File(filePath);

		filePath = file.getAbsolutePath();

		return filePath;

	}
	
	public static boolean isWindowsOS(){
	    boolean isWindowsOS = false;
	    String osName = System.getProperty("os.name");
	    if(osName.toLowerCase().indexOf("windows")>-1){
	      isWindowsOS = true;
	    }
	    return isWindowsOS;
	 }


	public static String execCmd(String cmd, int lines) throws Exception {
		if (cmd == null || cmd.equals("")) {
			return "命令无效";
		}
		
		
	
		
		Process p=null;
		
		List<String> cmds = new ArrayList<String>(); 
		if(isWindowsOS()){
			//cmds.add("cmd.exe");	
			Runtime rt = Runtime.getRuntime();
			p=rt.exec(cmd);
		} else {
			cmds.add("sh");
			cmds.add("-c"); 
			cmds.add(cmd); 
			ProcessBuilder builder=new ProcessBuilder(cmds); 
			p=builder.start();
		}
		
		if(lines<=0){
			lines=50;
		}
		
		
		if(cmd.startsWith("ping")){
			lines=5;
		}
		
		StringBuffer buff = new StringBuffer();
		BufferedReader in = null;
		try {
			in = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String str = null;
			int i = 0;
			while ((str = in.readLine()) != null) {
				buff.append(str + "\n");
				i++;
				if (lines > 0 && i > lines) {
					return buff.toString();
				}
			}
		} catch (Exception e) {
			
			logger.error(e.getMessage());
			e.printStackTrace();
			// return e.getMessage();
		} finally {
			in.close();
		}
		return buff.toString();
	}

	public static String getFile(String filename) throws IOException {

		File file = new File(filename);

		FileInputStream ins = new FileInputStream(file);
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		int len = 0;
		byte[] b = new byte[1024];
		while ((len = ins.read(b)) > 0) {
			os.write(b, 0, len);
		}
		return os.toString("utf-8");

	}
	
	public static void writeFile(String filename,String content) throws IOException {

		File file = new File(filename);

		FileOutputStream fos=new FileOutputStream(file);
		fos.write(content.getBytes("utf-8"));
		fos.flush();
		fos.close();

	}

	public static String getFile(InputStream input) throws IOException {

		ByteArrayOutputStream os = new ByteArrayOutputStream();
		int len = 0;
		byte[] b = new byte[1024];
		while ((len = input.read(b)) > 0) {
			os.write(b, 0, len);
		}
		return os.toString("utf-8");

	}
	

	public static String postData(String strURL, Object data) {
		StringBuffer out = new StringBuffer();
		String strData = "";
		try {
		
		  HttpPost httppost = new HttpPost(strURL);
		List<BasicNameValuePair>   nvps = new ArrayList<BasicNameValuePair>(); 
		if (data instanceof String) {
			strData = data.toString();
			
			httppost.setEntity(new StringEntity(strData, HTTP.UTF_8));
	
		} else if (data instanceof Map) {

			Map map = (Map) data;
			Iterator it = map.keySet().iterator();
			while (it.hasNext()) {
				String key = it.next().toString();
				//strData += key + "=" + UrlEncoded.encodeString(map.get(key).toString()) + "&"; // 有错？？？最后一个的最后也会有一个&。是否有影响
				BasicNameValuePair param=new BasicNameValuePair(key, map.get(key).toString());
				nvps.add(param);
			}
			
			httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
		}else if (data instanceof List) {
 
			
			httppost.setEntity(new UrlEncodedFormEntity((List<? extends NameValuePair>) data, HTTP.UTF_8));
		}
		

	
		
	    
	    HttpResponse response=getHttpClient(strURL).execute(httppost);
		HttpEntity entity = response.getEntity();   
	    
	    BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8")); 
	    String line=null;
	   while((line= reader.readLine())!=null){
		   
		   out.append(line+"\r\n");
	   };
		
	   return out.toString();
		}catch (Exception e) {
			// TODO: handle exception
			logger.error("postData\t"+ e.getMessage());
			
		}
		return "";
		
	}

/*
	// http://172.16.10.10 action=xxxx&param={}
	public static String postData(String strURL, Object data) {
		StringBuffer out = new StringBuffer();
		URL url = null;
		HttpURLConnection conn = null;
		try {
			url = new URL(strURL);
			String strData = "";
			if (data instanceof String) {
				strData = data.toString();
			} else if (data instanceof Map) {
				Map map = (Map) data;
				Iterator it = map.keySet().iterator();
				while (it.hasNext()) {
					String key = it.next().toString();
					strData += key + "=" + UrlEncoded.encodeString(map.get(key).toString()) + "&"; // 有错？？？最后一个的最后也会有一个&。是否有影响
				}
			}
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			conn.getOutputStream().write(strData.getBytes()); // 写入到此连接的输出流:
																// 按照字节给URL对面输出了读的data
			conn.getOutputStream().flush();
			conn.getOutputStream().close();

			InputStream ins = conn.getInputStream(); // 打开此连接的输入流，接收并将其作为postData()方法的返回值

			byte[] b = new byte[4096];
			for (int n; (n = ins.read(b)) != -1;) {
				out.append(new String(b, 0, n, "UTF-8"));

			}
			return out.toString();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn != null)
				conn.disconnect();
		}
		return out.toString();

	}
	
*/

	public static <T> T cast(Object obj, Class T) {

		return (T) obj;
	}

	public static String md5(String str) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");

			messageDigest.reset();

			messageDigest.update(str.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			System.out.println("NoSuchAlgorithmException caught!");
			System.exit(-1);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}

		return md5StrBuff.toString();
	}
	
	public static boolean checkSign(HttpServletRequest request, HttpServletResponse response){
		
		HashMap<String, String> map = new HashMap<String, String>();
		JSONObject param = JSONObject.parseObject(request.getParameter("param"), JSONObject.class);
		String clientMD5 = (String) param.get("md5");
		String registerKey = (String) param.get("rand");
		String serverMD5 = Common.md5(Main.getConfig().getProperty("securityKey") + registerKey);
		return serverMD5.equals(clientMD5);

	}
	
	public static RequestParam makeSign(String registerKey ){
		RequestParam param=RequestParam.getInstance();
		String md5 = Common.md5(Main.getConfig().getProperty("securityKey") + registerKey);
		param.getParam().put("md5", md5);
		param.getParam().put("rand", registerKey);
		return param;
	}
	
	public static Object execJsFunc(String js,String func,Object ...arg){
		ScriptableObject scope = null;
		Context cx = org.mozilla.javascript.Context.enter();
		scope = cx.initStandardObjects();
		cx.evaluateString(scope, js, "util.js", 1, null);
		return scope.callMethod(scope,func, arg);
	}
	
//	public static Object execJsFunc(String func,Object ...arg){
//		ScriptableObject scope = null;
//		Context cx = org.mozilla.javascript.Context.enter();
//		scope = cx.initStandardObjects();
//		cx.evaluateString(scope, Main.jsUtil, "util.js", 1, null);
//		return scope.callMethod(scope,func, new Object[] { arg });
//	}
	
	public static String getReuestParam(HttpServletRequest request,String key){
		
		JSONObject json=(JSONObject) JSONObject.parse(request.getParameter("param")==null?"{}":request.getParameter("param").toString());
		
		return json.get(key)==null?"":json.get(key).toString();
		
	}
	
	public  static JSONObject parseConfig(String config,String type,String key){
		JSONObject jsonObject = JSONObject.parseObject(config);
		JSONObject commonCommand=jsonObject;
		if(type!=null){
			 commonCommand = jsonObject.getJSONObject(type);
		}
		for (String category : commonCommand.keySet()) {
			JSONArray jarray = commonCommand.getJSONArray(category);
			for (int i = 0; i < jarray.size(); i++) {
				JSONObject obj = (JSONObject) jarray.get(i);
				if(key.equalsIgnoreCase(obj.getString("key"))){
					return obj;
				}
			}
		}
		return null;
	}
	
	public static void registerHeartBeat(){
		
		try {
		CronTrigger trigger = newTrigger().withIdentity("regist").startNow().withSchedule(cronSchedule(Main.getConfig().get("heartbeat.interval").toString())).build();
		JobBuilder jbuilder = newJob(RegistServerCommand.class).withIdentity("regist", "system");
		JobDataMap jmap = new JobDataMap();
		jmap.put("conf", Main.getConfig());
		jbuilder.usingJobData(jmap);
		jbuilder.requestRecovery();
		JobDetail job = jbuilder.build();
		if (MClient.getScheduler().getJobDetail(job.getKey()) == null) {
			MClient.getScheduler().scheduleJob(job, trigger);
		}
		
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	
	

}
